#include "boost/asio.hpp"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include "boost_service.h"
#include <string>

using namespace boost::asio;

io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), POINT); //定义监听商品
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));

void async()
{
    printf("register handle callback...\n");
    start_accept(sock);
    printf("Service runing...\n");
    service.run();
}

void handle_accept(socket_ptr sock, const boost::system::error_code &err)
{
    if (err)
    {
        printf("connection status : failed\n");
    }
    else if (err == error::eof)
    {
        printf("connection status : closed\n");
    }
    else if (err == error::already_connected)
    {
        printf("connection status : successed\n");
    }
    // 从这里开始, 你可以从socket读取或者写入
    read_data(*sock.get());

    socket_ptr sock2(new ip::tcp::socket(service));
    start_accept(sock2);
}

void start_accept(socket_ptr sock)
{
    acc.async_accept(*sock, boost::bind(handle_accept, sock, _1));
}

int read_data(ip::tcp::socket &sock)
{
    boost::system::error_code ec;

    // 从客户端读取数据
    char buf[BLOCK_SIZE];
    int len = sock.read_some(buffer(buf), ec);
    // 或者可以使用read_until读到某个字符为止
    // 或者可以使用某种判断方式循环读取

    if (ec)
    {
        std::cout << boost::system::system_error(ec).what() << std::endl;
    }
    std::cout.write(buf, len);
    std::cout << len << std::endl;

    send_data(sock);
    return len;
}

/**
 * @brief 向客户端发送
 * 
 * @param sock 
 * @return int 
 */
int send_data(ip::tcp::socket &sock)
{
    boost::system::error_code ec;
    std::string value = "Hello world from service ";
    size_t len = sock.write_some(buffer(value), ec);
    if (ec)
    {
        std::cout << boost::system::system_error(ec).what() << std::endl;
    }
    std::cout << "writed " << len << " : " + value << std::endl;
}

void sync2()
{
    io_service iosev;
    ip::tcp::acceptor acceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(), POINT));
    for (;;)
    {
        // socket对象
        ip::tcp::socket socket(iosev);
        // 等待直到客户端连接进来
        acceptor.accept(socket);
        // 显示连接进来的客户端
        std::cout << "client from: " << socket.remote_endpoint().address() << std::endl;
        read_data(socket);
        //Sleep(1000);
    }
}

int main(int argc, char const *argv[])
{
    {
        async();
    }
    {
        // sync();
    }
    return 0;
}

//g++ BoostService.cpp -lpthread -lboost_system -I/usr/local/include/boost -L/usr/local/lib -o service